using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace MaterialUI
{
	public class Ripple : Image
	{
		private static readonly double[] m_Tier1Coefficients = new double[5]
		{
			6.29601480149216,
			0.790101551206291,
			-0.262948117301137,
			0.00512416320905045,
			-3.80506669282087E-05
		};

		private static readonly double[] m_Tier2Coefficients = new double[5]
		{
			215687.256290898,
			-4.19735422974633,
			0.0951623635658089,
			-0.000309361330425578,
			-6.81012204738887E-08
		};

		private static readonly double[] m_Tier3Coefficients = new double[5]
		{
			1.35489672861472E+15,
			-10.6998485226718,
			0.190322732770353,
			-0.0006188525075537,
			8.94213533926328E-07
		};

		private static readonly double[] m_Tier4Coefficients = new double[5]
		{
			9.73229524743051E+16,
			-10.104765382165,
			0.0891692727750869,
			-0.000138147859622898,
			9.06760843587359E-08
		};

		private static readonly double[] m_Tier5Coefficients = new double[5]
		{
			0.00164932975085508,
			0.984071298443192,
			-0.0055147376298876,
			3.84368847512861E-06,
			-1.71500898423944E-09
		};

		private static readonly double[] m_Tier6Coefficients = new double[5]
		{
			0.000416750897989708,
			0.984141847866171,
			-0.00275751774737513,
			9.60973461097143E-07,
			-2.14384084088226E-10
		};

		private static readonly float m_Tier7Value = 0.01f;

		private int m_Id;

		private RippleData m_RippleData;

		private MaterialUIScaler m_Scaler;

		private CanvasGroup m_CanvasGroup;

		private IRippleCreator m_RippleCreator;

		private RectTransform m_RippleParent;

		private float m_CurrentAlpha;

		private float m_CurrentSize;

		private Vector3 m_CurrentPosition;

		private bool m_Oscillate;

		private float m_AnimationDuration;

		private float m_AnimStartTime;

		private float m_AnimDeltaTime;

		private int m_State;

		private static Material m_RippleMaterial;

		private static bool m_MaterialIsReset = false;

		private static List<int> m_AverageSizes = new List<int>();

		public int id
		{
			get
			{
				return m_Id;
			}
			set
			{
				m_Id = value;
			}
		}

		public RippleData rippleData => m_RippleData;

		public MaterialUIScaler scaler
		{
			get
			{
				if (m_Scaler == null)
				{
					m_Scaler = MaterialUIScaler.GetParentScaler(base.rectTransform);
				}
				return m_Scaler;
			}
		}

		public CanvasGroup canvasGroup => m_CanvasGroup;

		private void OnApplicationQuit()
		{
			ResetMaterial();
		}

		public static void ResetMaterial()
		{
			if (!m_MaterialIsReset)
			{
				m_MaterialIsReset = true;
				if (m_RippleMaterial != null)
				{
					m_RippleMaterial.SetFloat("_Softening", 0.25f);
				}
			}
		}

		public void Create(int id, VectorImageData imageData)
		{
			if (m_Id != 0)
			{
				UnityEngine.Debug.Log("Cannot Setup a Ripple more than once");
				return;
			}
			m_Id = id;
			m_CanvasGroup = GetComponent<CanvasGroup>();
			if (m_RippleMaterial == null)
			{
				m_RippleMaterial = m_Material;
			}
		}

		public void ClearData()
		{
			m_RippleData = null;
		}

		public void Setup(RippleData data, Vector2 positon, IRippleCreator creator, bool oscillate = false)
		{
			m_RippleData = data;
			m_RippleParent = (RectTransform)data.RippleParent;
			base.rectTransform.SetParent(m_RippleParent);
			base.rectTransform.SetSiblingIndex(0);
			m_Oscillate = oscillate;
			base.rectTransform.sizeDelta = Vector2.zero;
			Camera camera = UnityEngine.Object.FindObjectOfType<Camera>();
			switch (GetComponentInParent<Canvas>().renderMode)
			{
			case RenderMode.ScreenSpaceOverlay:
			{
				RectTransform rectTransform3 = base.rectTransform;
				float x3 = positon.x;
				float y3 = positon.y;
				Vector3 position5 = m_RippleParent.position;
				rectTransform3.position = new Vector3(x3, y3, position5.z);
				break;
			}
			case RenderMode.ScreenSpaceCamera:
			{
				RectTransform rectTransform2 = base.rectTransform;
				Vector3 position3 = camera.transform.position;
				Camera camera3 = camera;
				Vector3 mousePosition3 = UnityEngine.Input.mousePosition;
				float x2 = mousePosition3.x;
				Vector3 mousePosition4 = UnityEngine.Input.mousePosition;
				float y2 = mousePosition4.y;
				Vector3 position4 = m_RippleParent.position;
				Ray ray2 = new Ray(position3, camera3.ScreenToWorldPoint(new Vector3(x2, y2, position4.z)));
				rectTransform2.position = ray2.GetPoint(Vector3.Distance(camera.transform.position, m_RippleParent.position));
				break;
			}
			case RenderMode.WorldSpace:
			{
				RectTransform rectTransform = base.rectTransform;
				Vector3 position = camera.transform.position;
				Camera camera2 = camera;
				Vector3 mousePosition = UnityEngine.Input.mousePosition;
				float x = mousePosition.x;
				Vector3 mousePosition2 = UnityEngine.Input.mousePosition;
				float y = mousePosition2.y;
				Vector3 position2 = m_RippleParent.position;
				Ray ray = new Ray(position, camera2.ScreenToWorldPoint(new Vector3(x, y, position2.z)));
				rectTransform.position = ray.GetPoint(Vector3.Distance(camera.transform.position, m_RippleParent.position));
				break;
			}
			}
			base.rectTransform.localEulerAngles = Vector3.zero;
			color = data.Color;
			canvasGroup.alpha = data.StartAlpha;
			m_AnimationDuration = 4f / data.Speed;
			m_RippleCreator = creator;
			if (data.PlaceRippleBehind)
			{
				int siblingIndex = m_RippleParent.GetSiblingIndex();
				base.rectTransform.SetParent(m_RippleParent.parent);
				base.rectTransform.SetSiblingIndex(siblingIndex);
			}
		}

		private float CalculateSize()
		{
			float num;
			if (rippleData.AutoSize)
			{
				Vector2 properSize = base.rectTransform.parent.GetComponent<RectTransform>().GetProperSize();
				float x = properSize.x;
				Vector2 properSize2 = base.rectTransform.parent.GetComponent<RectTransform>().GetProperSize();
				float y = properSize2.y;
				if (rippleData.SizeMode == RippleData.SizeModeType.FillRect)
				{
					x *= x;
					y *= y;
					x *= rippleData.SizePercent / 100f;
					y *= rippleData.SizePercent / 100f;
					num = Mathf.Sqrt(x + y);
				}
				else
				{
					num = Mathf.Max(x, y);
				}
			}
			else
			{
				num = rippleData.ManualSize;
			}
			if (m_Oscillate)
			{
				num *= 0.75f;
			}
			return num;
		}

		public void Expand()
		{
			base.rectTransform.localScale = Vector3.one;
			m_RippleCreator.OnCreateRipple();
			m_CurrentAlpha = canvasGroup.alpha;
			m_CurrentSize = base.rectTransform.rect.width;
			m_CurrentPosition = base.rectTransform.position;
			SubmitSizeForSoftening();
			m_AnimStartTime = Time.realtimeSinceStartup;
			m_State = 1;
		}

		public void Contract()
		{
			m_CurrentAlpha = canvasGroup.alpha;
			m_CurrentSize = base.rectTransform.rect.width;
			m_CurrentPosition = base.rectTransform.position;
			SubmitSizeForSoftening();
			m_AnimStartTime = Time.realtimeSinceStartup;
			m_State = 2;
		}

		private void Update()
		{
			m_AnimDeltaTime = Time.realtimeSinceStartup - m_AnimStartTime;
			if (m_State == 1)
			{
				if (m_AnimDeltaTime <= m_AnimationDuration)
				{
					canvasGroup.alpha = Tween.QuintOut(m_CurrentAlpha, rippleData.EndAlpha, m_AnimDeltaTime, m_AnimationDuration);
					float num = Tween.QuintOut(m_CurrentSize, CalculateSize(), m_AnimDeltaTime, m_AnimationDuration);
					base.rectTransform.sizeDelta = new Vector2(num, num);
					SubmitSizeForSoftening();
					if (rippleData.MoveTowardCenter)
					{
						Vector3 positionRegardlessOfPivot = m_RippleParent.GetPositionRegardlessOfPivot();
						RectTransform rectTransform = base.rectTransform;
						Vector3 currentPosition = m_CurrentPosition;
						float x = positionRegardlessOfPivot.x;
						float y = positionRegardlessOfPivot.y;
						Vector3 position = m_RippleParent.position;
						rectTransform.position = Tween.QuintOut(currentPosition, new Vector3(x, y, position.z), m_AnimDeltaTime, m_AnimationDuration);
					}
				}
				else if (m_Oscillate)
				{
					m_State = 3;
					m_AnimStartTime = Time.realtimeSinceStartup;
					m_CurrentSize = base.rectTransform.rect.width;
					m_CurrentSize *= 0.95f;
				}
				else
				{
					m_State = 0;
				}
			}
			else if (m_State == 2)
			{
				if (m_AnimDeltaTime <= m_AnimationDuration * 2f)
				{
					canvasGroup.alpha = Tween.QuintOut(m_CurrentAlpha, 0f, m_AnimDeltaTime, m_AnimationDuration * 2f);
					float num2 = Tween.QuintOut(m_CurrentSize, CalculateSize(), m_AnimDeltaTime, m_AnimationDuration);
					base.rectTransform.sizeDelta = new Vector2(num2, num2);
					SubmitSizeForSoftening();
					if (rippleData.MoveTowardCenter)
					{
						Vector3 positionRegardlessOfPivot2 = m_RippleParent.GetPositionRegardlessOfPivot();
						RectTransform rectTransform2 = base.rectTransform;
						Vector3 currentPosition2 = m_CurrentPosition;
						float x2 = positionRegardlessOfPivot2.x;
						float y2 = positionRegardlessOfPivot2.y;
						Vector3 position2 = m_RippleParent.position;
						rectTransform2.position = Tween.QuintOut(currentPosition2, new Vector3(x2, y2, position2.z), m_AnimDeltaTime, m_AnimationDuration);
					}
				}
				else
				{
					m_State = 0;
					m_RippleCreator.OnDestroyRipple();
					RippleManager.instance.ReleaseRipple(this);
				}
			}
			else if (m_State == 3)
			{
				float num3 = Tween.Sin(m_CurrentSize, m_CurrentSize * 0.05f, m_AnimDeltaTime * 4f);
				base.rectTransform.sizeDelta = new Vector2(num3, num3);
				SubmitSizeForSoftening();
			}
		}

		private void LateUpdate()
		{
			if (m_AverageSizes.Count > 0)
			{
				CalculateAverageSoftening();
			}
		}

		public void SubmitSizeForSoftening()
		{
			Vector2 properSize = base.rectTransform.GetProperSize();
			float x = properSize.x;
			Vector2 properSize2 = base.rectTransform.GetProperSize();
			float num = (x + properSize2.y) / 2f;
			if (scaler != null)
			{
				num *= scaler.scaler.scaleFactor;
			}
			m_AverageSizes.Add(Mathf.FloorToInt(num));
		}

		private static void CalculateAverageSoftening()
		{
			float num = 0f;
			float num2 = 0f;
			int num3 = 0;
			if (m_AverageSizes.Count == 1)
			{
				num2 = m_AverageSizes[0];
			}
			else
			{
				for (int i = 0; i < m_AverageSizes.Count; i++)
				{
					num += (float)m_AverageSizes[i];
				}
				for (int j = 0; j < m_AverageSizes.Count; j++)
				{
					if (m_AverageSizes[j] > 5 && Mathf.Abs((float)m_AverageSizes[j] - num) < 1000f)
					{
						num2 += (float)m_AverageSizes[j];
						num3++;
					}
				}
				num2 /= (float)num3;
			}
			float num4 = (num2 >= 2000f) ? m_Tier7Value : ((num2 >= 1000f) ? PowerExp(num2, m_Tier6Coefficients) : ((num2 >= 500f) ? PowerExp(num2, m_Tier5Coefficients) : ((num2 >= 200f) ? PowerExp(num2, m_Tier4Coefficients) : ((num2 >= 100f) ? PowerExp(num2, m_Tier3Coefficients) : ((!(num2 >= 50f)) ? PowerExp(num2, m_Tier1Coefficients) : PowerExp(num2, m_Tier2Coefficients))))));
			m_RippleMaterial.SetFloat("_Softening", 0.5f * ((!float.IsNaN(num4)) ? num4 : 0.25f));
			m_AverageSizes = new List<int>();
		}

		private static float PowerExp(float x, double[] c)
		{
			return (float)(c[0] * Math.Pow(x, c[1]) * Math.Pow(Math.E, c[2] * (double)x + c[3] * (double)Mathf.Pow(x, 2f) + c[4] * (double)Mathf.Pow(x, 3f)));
		}

		protected override void OnPopulateMesh(VertexHelper vh)
		{
			base.OnPopulateMesh(vh);
			List<UIVertex> list = new List<UIVertex>();
			List<int> list2 = new List<int>();
			vh.GetUIVertexStream(list);
			vh.Clear();
			for (int i = 0; i < list.Count; i++)
			{
				UIVertex value = list[i];
				value.position *= 1.332f;
				value.position += new Vector3(2.209f, 0f, 0f) * ((value.position.x < 0f) ? 1 : (-1));
				value.position += new Vector3(0f, 2.209f, 0f) * ((value.position.y < 0f) ? 1 : (-1));
				list[i] = value;
				list2.Add(i);
			}
			vh.AddUIVertexStream(list, list2);
		}
	}
}
